//轮流打印ABC，属于线程轮流单独执行，悲观锁，不行就wait，可以就结束全部唤醒。如果是线程轮流执行同一个函数里的公告数据，对公共数据的操作上锁即可。
//这里完全可以只通过ready这个全局变量达到锁的目的，锁本质上就是一个公共数据的使用。然后这种属于乐观锁，抢不到就一直自旋。
#include <iostream>
#include <thread>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
int ready = 0;
using namespace std;
void PrintString_1()
{
    unique_lock<mutex> lk(mtx);
    int cnt = 0;
    while (cnt < 10)
    {
        while (ready != 0)
            cv.wait(lk);
        cout << this_thread::get_id() << " : " << "A" << endl;
        ready = 1;
        cnt++;
        cv.notify_all();
    }
}

void PrintString_2()
{
    unique_lock<mutex> lk(mtx);
    int cnt = 0;
    while (cnt < 10)
    {
        while (ready != 1)
            cv.wait(lk);
        cout << this_thread::get_id() << " : " << "B" << endl;
        ready = 2;
        cnt++;
        cv.notify_all();
    }
    /*
        int cnt = 0;
    while (cnt < 10)
    {
        while (ready == 1)
        {
            //mtx.lock();
            cout << this_thread::get_id() << " : " << "B" << endl;
            ready = 2;
            cnt++;
            //mtx.unlock();
        }

        
    }
    */
}

void PrintString_3()
{
    unique_lock<mutex> lk(mtx);
    int cnt = 0;
    while (cnt < 10)
    {
        while (ready != 2)
            cv.wait(lk);
        cout << this_thread::get_id() << " : " << "C" << endl;
        ready = 0;
        cnt++;
        cv.notify_all();
    }
}

int main()
{
    thread  t1(PrintString_1);
    thread  t2(PrintString_2);
    thread  t3(PrintString_3);
    t1.join();
    t2.join();
    t3.join();

    return 0;
}